package com.yy.device.controller;


import com.alibaba.fastjson.JSON;
import com.google.common.collect.Maps;
import com.yy.device.api.TaskApi;
import com.yy.device.api.web.APIModel;
import com.yy.device.api.web.APIModelHandler;
import com.yy.device.boot.DeviceDataContainer;
import com.yy.device.boot.protocol.TaskMessage;
import com.yy.device.core.service.TaskService;
import com.yy.device.enums.DeviceDataEnum;
import com.yy.device.enums.DeviceFunctionEnum;
import com.yy.util.Assert;
import com.yy.util.Snowflake;
import io.netty.channel.ChannelHandlerContext;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@RestController
@RequestMapping(("/tools/device"))
public class TestController {
    @Resource
    private TaskApi taskApi;
    @Resource
    private TaskService taskService;

    @RequestMapping("/getOnlineDevices")
    public Object getOnlineDevices() {
        Map<Integer, ChannelHandlerContext> devices = DeviceDataContainer.getOnlineDevices();
        HashMap<String, Object> result = Maps.newHashMapWithExpectedSize(devices.size());
        for (Map.Entry<Integer, ChannelHandlerContext> entry : devices.entrySet()) {
            Integer deviceCode = entry.getKey();
            result.put("deviceCode-" + deviceCode, entry.getValue());
        }
        return result;
    }

    @RequestMapping("/monitor")
    public Object monitor() {
//        DeviceDataContainer.DEVICE_DATA_MAP.put(33806, Arrays.asList((short) 0
//                , (short) 0
//                , (short) 0
//                , (short) 0
//                , (short) 0
//                , (short) 0
//                , (short) 0
//                , (short) 0
//                , (short) 0
//                , (short) 0
//                , (short) 0
//                , (short) 0
//                , (short) 0
//                , (short) 0
//                , (short) 0
//                , (short) 0
//        ));
        List<MonitorVo> list = new ArrayList<>();
        for (Map.Entry<Integer, List<Short>> entry : DeviceDataContainer.DEVICE_DATA_MAP.entrySet()) {
            MonitorVo monitorVo = new MonitorVo();
            monitorVo.setName(entry.getKey());
            List<Short> value = entry.getValue();
            List<Short> left = value.stream().skip(0).limit(8).collect(Collectors.toList());
            List<Short> right = value.stream().skip(16).limit(8).collect(Collectors.toList());


            monitorVo.setValueLeft(left);
            monitorVo.setValueRight(right);
            list.add(monitorVo);
        }
        return "hello(" + JSON.toJSONString(list) + ")";
    }

    @RequestMapping("/send")
    public Object send(TaskVo taskVo) {
        return APIModelHandler.execute(model -> {
            Assert.isTrue(!Objects.isNull(taskVo), "参数不允许是null");
            Assert.isTrue(!Objects.isNull(taskVo.getDeviceCode()), "设备编码不允许是null");
            Assert.isTrue(!Objects.isNull(taskVo.getDataCommand()), "开关状态不允许是null");
            Assert.isTrue(!Objects.isNull(taskVo.getDevicePointCode()), "寄存器编号不允许是null");
            Assert.isTrue(taskVo.getDataCommand() == 0 || taskVo.getDataCommand() == 1, "开关状态只能是0或者1");
            Assert.isTrue(taskVo.getDevicePointCode() >= 0 && taskVo.getDevicePointCode() < 8, "寄存器编号只能在0-7之间");
            taskVo.setFunctionCommand(6);

            TaskMessage taskMessage = TaskMessage.createSend(DeviceFunctionEnum.getEnumByType(taskVo.getFunctionCommand()),
                    DeviceDataEnum.getEnumByType(taskVo.getDataCommand().shortValue()),
                    taskVo.getDevicePointCode()
            );
            APIModel apiModel = taskApi.command(taskVo.getDeviceCode(), taskMessage);
            model.setData(apiModel.getData());
        });

    }

    @RequestMapping("/query")
    public Object query(@RequestBody TaskVo taskVo) {

        return APIModelHandler.execute(model -> {
            Assert.isTrue(!Objects.isNull(taskVo), "参数不允许是null");
            Assert.isTrue(!Objects.isNull(taskVo.getDeviceCode()), "设备编码不允许是null");
            Assert.isTrue(!Objects.isNull(taskVo.getDevicePointCode()), "寄存器编号不循序是null");
            Assert.isTrue(taskVo.getDevicePointCode() >= 0 && taskVo.getDevicePointCode() < 16, "寄存器编号只能在0-15之间");
            taskVo.setDataCommand(1);
            taskVo.setFunctionCommand(3);
            long taskId = Snowflake.nextId();
            TaskMessage taskMessage = TaskMessage.createSend(DeviceFunctionEnum.getEnumByType(taskVo.getFunctionCommand()),
                    DeviceDataEnum.getEnumByType(taskVo.getDataCommand().shortValue()),
                    taskVo.getDevicePointCode(),
                    taskId
            );
            taskApi.command(taskVo.getDeviceCode(), taskMessage);
            model.setData(taskId);
        });

    }

    /**
     * 设备注册监控
     *
     * @return {@link Object}
     */
    @RequestMapping("/getCommandMap")
    public Object getCommandMap() {
        return taskService.findNewTaskList();
    }
}
